﻿namespace EFS.RC.SupervisorCentral.Controls.Agents
{
	public class List : System.Windows.Controls.UserControl
	{
		#region Delegates
		/// delegates
		public delegate void LoadAgentsDelegate();

		/// Button cliked
		public EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem.ButtonClickedDlg ContactListItem_OnButtonClickedDlg;
		#endregion

		#region Locals
		/// timer clean
		private System.Windows.Threading.DispatcherTimer timerClean = null;
		#endregion

		#region Constructors
		/// Implicit
		public List()
		{
			// ignore in design tool
			if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
			{
				this.Loaded += new System.Windows.RoutedEventHandler(List_Loaded);
				this.Unloaded += new System.Windows.RoutedEventHandler(List_Unloaded);
			}
		}
		#endregion

		#region Properties
		/// Property CustomerEndPoint: Get, Set
		public EFS.RC.CC.Messages.Application.CustomerEndPoint CustomerEndPoint { get; set; }

		/// Properties AgentsLoaded: Get, Set
		public System.Boolean AgentsLoaded { get; private set; }

		/// Property WrapPanelAgents: Get
		protected virtual System.Windows.Controls.WrapPanel WrapPanelAgents
		{
			get
			{
				throw new System.NotImplementedException("WrapPanelAgents");
			}
		}

		/// Property AgentStatuses: Get
		public virtual EFS.RC.CC.Messages.Agents.Status[] AgentItems
		{
			get
			{
				throw new System.NotImplementedException("AgentItems");
			}
		}

		/// Property ContactListItemNewInstance: Get
		protected virtual EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem ContactListItemNewInstance
		{
			get
			{
				throw new System.NotImplementedException("ContactListItemNewInstance");
			}
		}
		#endregion

		#region UI
		#endregion

		#region Utilities
		/// Can Monitor
		public static System.Boolean CanMonitor(
			EFS.RC.CC.Messages.Agents.Status agentInfo)
		{
			// check
			EFS.Common.Verify.Reference(agentInfo, "agentInfo");

			// ok
			return
				agentInfo.IsOnline && agentInfo.InSession && (agentInfo.ConversationInfo.Monitoring == EFS.RC.CC.Messages.Communicator.Lync.Conversation.Info.MonitoringStatus.None);
		}

			#region Clean
		/// Start clean
		private void StartClean()
		{
			// stop clean
			StopClean();

			timerClean = new System.Windows.Threading.DispatcherTimer();
			timerClean.Interval = new System.TimeSpan(0, 0, 1, 0, 0);
			timerClean.Tick += new System.EventHandler(timerClean_Tick);
			timerClean.Start();
		}

		/// Clean sequence
		private void timerClean_Tick(object sender, System.EventArgs e)
		{
			lock (WrapPanelAgents)
			{
				// create remove list
				System.Collections.Generic.List<EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem> removeList =
					new System.Collections.Generic.List<EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem>();

				// cicle all in panel
				foreach (EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem item in WrapPanelAgents.Children)
				{
					// get time span last updated
					System.TimeSpan tsLastUpdate = System.DateTime.Now - item.LastUpdate;
					if (tsLastUpdate.Minutes >= 1)
					{
						removeList.Add(item);
					}
				}

				// cicle all and remove
				foreach (EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem item in removeList)
				{
					RemoveAgentItem(item);
				}
			}
		}

		/// Stop Clean
		public void StopClean()
		{
			// stop waiting
			if (null != timerClean && timerClean.IsEnabled)
			{
				timerClean.Stop();
				timerClean = null;
			}
		}
			#endregion
		#endregion

		#region ItemsManipulation
		/// Add/Update agents
		public void AddUpdateAgents()
		{
			lock (WrapPanelAgents)
			{
				if (AgentsLoaded)
				{
					UpdateAgents();
				}
				else
				{
					LoadAgents();
				}
			}
		}

		/// UpdateAgents
		private void UpdateAgents()
		{
			// get agents
			EFS.RC.CC.Messages.Agents.Status[] agentArray = AgentItems;

			// remove list
			System.Collections.Generic.List<EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem> itemsToBeRemoved =
				new System.Collections.Generic.List<EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem>();

			// add list
			System.Collections.Generic.List<EFS.RC.CC.Messages.Agents.Status> itemsToBeAdded =
				new System.Collections.Generic.List<EFS.RC.CC.Messages.Agents.Status>();

			// update list
			System.Collections.Generic.Dictionary<EFS.RC.CC.Messages.Agents.Status, EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem> itemsToBeUpdated =
				new System.Collections.Generic.Dictionary<EFS.RC.CC.Messages.Agents.Status, EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem>();

			// cicle all in panel
			foreach (EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem item in WrapPanelAgents.Children)
			{
				// flags
				System.Boolean existsInSession = false;

				// cicle all in session list (this are the valid ones)
				foreach (EFS.RC.CC.Messages.Agents.Status agentStatus in agentArray)
				{
					// test sip
					if (0 == System.String.Compare(item.Source, agentStatus.SIP, true))
					{
						itemsToBeUpdated[agentStatus] = item;
						existsInSession = true;
						break;
					}
				}

				// remove?
				if (!existsInSession)
				{
					itemsToBeRemoved.Add(item);
				}
			}

			// cicle all in session list (this are the valid ones)
			foreach (EFS.RC.CC.Messages.Agents.Status agentStatus in agentArray) 
			{
				// flags
				System.Boolean existsInPanel = false;

				// cicle all in panel
				foreach (EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem item in WrapPanelAgents.Children)
				{
					// test sip
					if (0 == System.String.Compare(item.Source, agentStatus.SIP, true))
					{
						existsInPanel = true;
						break;
					}
				}

				// remove?
				if (!existsInPanel)
				{
					itemsToBeAdded.Add(agentStatus);
				}
			}

			// update
			foreach (EFS.RC.CC.Messages.Agents.Status agentStatus in itemsToBeUpdated.Keys)
			{
				EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem item = (EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem)itemsToBeUpdated[agentStatus];
				UpdateAgentItem(item, agentStatus);
			}

			// remove
			foreach (EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem item in itemsToBeRemoved)
			{
				RemoveAgentItem(item);
			}

			// add
			foreach (EFS.RC.CC.Messages.Agents.Status agentStatus in itemsToBeAdded)
			{
				AddAgentItem(agentStatus);
			}
		}

		/// LoadAgents
		private void LoadAgents()
		{
			// clear all previous
			WrapPanelAgents.Children.Clear();

			// get all
			EFS.RC.CC.Messages.Agents.Status[] agentArray = AgentItems;

			// cicle all
			foreach (EFS.RC.CC.Messages.Agents.Status agentInfo in agentArray)
			{
				AddAgentItem(agentInfo);
			}

			// set loaded
			AgentsLoaded = true;
		}

		/// Add agent row
		protected virtual void AddAgentItem(
			EFS.RC.CC.Messages.Agents.Status agentObj)
		{
			// check
			EFS.Common.Verify.Reference(agentObj, "agentObj");

			// create new
			EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem contactListItem = ContactListItemNewInstance;
			contactListItem.ACD = CustomerEndPoint.PhoneUri;
			contactListItem.RequiredSkillId = CustomerEndPoint.RequiredSkillId;
			contactListItem.OnButtonClickedDlg += ContactListItem_OnButtonClicked;

			// add
			WrapPanelAgents.Children.Add(contactListItem);

			// add row
			UpdateAgentItem(contactListItem, agentObj);
		}

		/// Updates an agent row
		protected virtual void UpdateAgentItem(
			EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem contactListItem,
			EFS.RC.CC.Messages.Agents.Status agentObj)
		{
			// check
			EFS.Common.Verify.Reference(contactListItem, "contactListItem");
			EFS.Common.Verify.Reference(agentObj, "agentObj");

			// update
			contactListItem.Source = agentObj.SIP;
			contactListItem.Update();
		}

		/// Removes the row agent
		protected void RemoveAgentItem(EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem contactListItem)
		{
			// check
			EFS.Common.Verify.Reference(contactListItem, "contactListItem");

			// remove
			WrapPanelAgents.Children.Remove(contactListItem);
		}

		/// Removes the agent denoted by the sip
		protected void RemoveAgentItem(System.String sip)
		{
			// check
			EFS.Common.Verify.String(sip, "sip");

			// cicle all
			foreach (EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem contactListItem in WrapPanelAgents.Children)
			{
				// test sip
				if (0 == System.String.Compare(contactListItem.Source, sip, true))
				{
					RemoveAgentItem(contactListItem);
					break;
				}
			}
		}
		#endregion

		#region Events
		/// Loaded
		private void List_Loaded(object sender, System.Windows.RoutedEventArgs e)
		{
			StartClean();
		}

		/// UnLoaded
		private void List_Unloaded(object sender, System.Windows.RoutedEventArgs e)
		{
			StopClean();
		}
		#endregion

		#region ControlEvents
		/// ContactListItem_OnButtonClicked
		private void ContactListItem_OnButtonClicked(
			System.Windows.RoutedEventArgs routedEventArgs,
			EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem.eButtonType buttonType,
			System.String agentSIP,
			System.String acd)
		{
			// call registered handlers
			if (null != this.ContactListItem_OnButtonClickedDlg)
			{
				this.ContactListItem_OnButtonClickedDlg(routedEventArgs, buttonType, agentSIP, CustomerEndPoint.PhoneUri);
			}
		}
		#endregion
	}

}